package cn.nexd.location.collector.core.collectors;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import cn.nexd.location.collector.NexdCollector;
import cn.nexd.location.collector.NexdCollectorConfig;
import cn.nexd.location.collector.bean.WifiCollectorResult;
import cn.nexd.location.collector.core.WifiCollector;
import cn.nexd.location.utils.threadpool.ThreadTaskObject;
import cn.nexd.location.utils.threadpool.core.ThreadPoolDelegate;

/**
 * Created by codingfish on 15/9/28.
 */
final class WifiCollectorTask extends WifiCollector {

    /**
     * addNetwork(WifiConfiguration config) 添加一个config描述的WIFI网络，默认情况下，这个WIFI网络是DISABLE状态的。
     * calculateSignalLevel(int rssi , int numLevels) 计算信号的等级
     * compareSignalLevel(int rssiA, int rssiB) 对比网络A和网络B的信号强度
     * createWifiLock(int lockType, String tag) 创建一个WIFI 锁，锁定当前的WIFI连接
     * disableNetwork(int netId) 让一个网络连接失效
     * disconnect() 断开当前的WIFI连接
     * enableNetwork(int netId, Boolean disableOthers) 连接netId所指的WIFI网络，并是其他的网络都被禁用
     * getConfiguredNetworks() 获取网络连接的状态
     * getConnectionInfo() 获取当前连接的信息
     * getDhcpInfo() 获取DHCP 的信息
     * getScanResulats() 获取扫描测试的结果
     * getWifiState() 获取当前WIFI设备的状态
     * isWifiEnabled() 判断WIFI设备是否打开
     * pingSupplicant() ping操作，和PC的ping操作相同作用
     * ressociate() 重新连接WIFI网络，即使该网络是已经被连接上的
     * reconnect() 重新连接一个未连接上的WIFI网络
     * removeNetwork() 移除某一个网络
     * saveConfiguration() 保留一个配置信息
     * setWifiEnabled() 让一个连接有效
     * startScan() 开始扫描
     * updateNetwork(WifiConfiguration config) 更新一个网络连接
     * ///////////////////////
     * getBSSID() 获取BSSID属性
     * getDetailedStateOf() 获取客户端的连通性
     * getHiddenSSID() 获取SSID 是否被隐藏
     * getIpAddress() 获取IP 地址
     * getLinkSpeed() 获取连接的速度
     * getMacAddress() 获取Mac 地址
     * getRssi() 获取802.11n 网络的信号
     * getSSID() 获取SSID
     * getSupplicanState() 获取具体客户端状态的信息
     */

    private WifiManager wifiManager = null;


    //    private Handler handler = null;

    private Handler handler = null;
    private List<WifiCollectorResult> wifiCollectorResults;

    private long wifiResultCollectorTime = 0L;

    private long wifiResultCollectorStartTime = 0L;
    private long wifiresultCollectorEndTime = 0L;

    private boolean collectorTaskStoped = false;

    private WifiCollectorResult wifiCollectorResultClone;


    public WifiCollectorTask(Context context, NexdCollectorConfig collectorConfig, WifiCollectorListener wifiCollectorListener) {
        super(context, collectorConfig, wifiCollectorListener);
    }

    @Override
    public boolean initilazeCollector() {
        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

        // wifi Manager 初始化失败。什么情况下会出现？难道是设备没有 wifi 芯片？
        if (wifiManager == null && wifiCollectorListener != null) {
            wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGE_COLLECTOR_UNAVAILABLE);
            return false;
        }

        // wifi 状态为WIFI_STATE_ENABLED 时，表示 wifi 可用。
        // WIFI_STATE_ENABLED wifi 可用
        // WIFI_STATE_DISABLED wifi 已经关闭
        // WIFI_STATE_DISABLING wifi 正在关闭
        // WIFI_STATE_ENABLING wifi 正在打开
        // WIFI_STATE_UNKNOWN wifi 状态未知
        if (wifiManager.getWifiState() == WifiManager.WIFI_STATE_UNKNOWN || wifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING || wifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
            wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGG_COLLECTOR_STATE_UNAVAILABLE);
            return false;
        }
        return true;
    }

    @Override
    public boolean startCollector() {

        collectorTaskStoped = false;
        wifiCollectorResultClone = new WifiCollectorResult();
        handler = new WifiCollectorTaskHandler();
        wifiCollectorResults = new ArrayList<WifiCollectorResult>();
        wifiResultCollectorStartTime = System.currentTimeMillis();
        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(getCollectorTask());
        return true;
    }

    private WifiCollectorTaskThread getCollectorTask() {
        //        final WifiCollectorTaskThread wifiCollectorTaskThread = new WifiCollectorTaskThread();
        final WeakReference<WifiCollectorTaskThread> wifiCollectorTaskThreadWeakReference = new WeakReference<WifiCollectorTaskThread>(new WifiCollectorTaskThread());
        return wifiCollectorTaskThreadWeakReference.get();
        //        return wifiCollectorTaskThread;
    }

    @Override
    public boolean stopCollector() {
        this.collectorTaskStoped = true;
        if (wifiCollectorResults != null) {
            wifiCollectorResults.clear();
        }
        return true;
    }

    @Override
    public boolean destroyCollector() {
        if (wifiManager != null) {
            wifiManager = null;
        }
        if (wifiCollectorListener != null) {
            wifiCollectorListener = null;
        }

        if (wifiCollectorResults != null) {
            wifiCollectorResults = null;
        }
        if (handler != null) {
            handler = null;
        }

        if (context != null) {
            context = null;
        }
        collectorTaskStoped = false;
        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().stopAllTask();
        return true;
    }

    private static final int HANDLER_MESSAGE_WIFIMANAGER_NULL = 0x271a;
    private static final int HANDLER_MESSAGE_WIFI_STATE_DISABLED = 0x271b;
    private static final int HANDLER_MESSAGE_WIFI_STATE_ENABLING = 0x271c;
    private static final int HANDLER_MESSAGE_WIFI_STATE_UNKNOWN = 0x271d;
    private static final int HANDLER_MESSAGE_WIFI_SCANRESULT_NULL = 0x271e;
    private static final int HANDLER_MESSAGE_WIFI_HANDLER_SCANRESULT = 0x271f;
    private static final int HANDLER_MESSAGE_WIFI_FUCK_360 = 0x272a;
    private static final int HANDLER_MESSAGE_WIFI_SCAN_SUCCESS = 0x2724;

    private class WifiCollectorTaskThread extends ThreadTaskObject {

        @Override
        public void run() {
            if (wifiManager == null) {
                if (handler != null) {
                    handler.sendEmptyMessage(HANDLER_MESSAGE_WIFIMANAGER_NULL);
                }
                return;
            }

            if (wifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
                // wifi 不可用
                switch (wifiManager.getWifiState()) {
                    case WifiManager.WIFI_STATE_DISABLED://已经关闭
                    case WifiManager.WIFI_STATE_DISABLING://正在关闭
                        if (handler != null) {
                            handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_STATE_DISABLED);
                        }
                        return;
                    case WifiManager.WIFI_STATE_ENABLING:// 正在打开

                        try {
                            Thread.sleep(collectorConfig.wifiCollectorRate);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (handler != null) {
                            handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_STATE_ENABLING);
                        }
                        return;
                    case WifiManager.WIFI_STATE_UNKNOWN:// 状态未知
                        if (handler != null) {
                            handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_STATE_UNKNOWN);
                        }
                        return;
                }
            }

            wifiResultCollectorTime = System.currentTimeMillis();
            if (wifiManager != null) {
                wifiManager.startScan();
            }
            wifiresultCollectorEndTime = System.currentTimeMillis();

            List<ScanResult> scanResults = wifiManager.getScanResults();

            //            Log.d("wifi_data_test", "**** " + scanResults.size());
            if (scanResults != null && scanResults.size() > 0) {
                wifiCollectorResults.clear();

                //判断是不是被狗日的360拦截了

                if (scanResults.size() == 1 && TextUtils.equals("00:00:00:00:00:00", scanResults.get(0).BSSID)) {
                    //狗日的360
                    //狗日的腾讯
                    //狗日的 LBE
                    //狗日的百度
                    //狗日的一切流氓
                    handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_FUCK_360);
                    return;
                }
                for (ScanResult scanResult : scanResults) {
                    WifiCollectorResult wifiCollectorResult = null;
                    try {
                        wifiCollectorResult = wifiCollectorResultClone.clone();
                    } catch (CloneNotSupportedException e) {
                        wifiCollectorResultClone = new WifiCollectorResult();
                    }
                    //                    WifiCollectorResult wifiCollectorResult = new WifiCollectorResult();
                    //                    WifiCollectorResult wifiCollectorResult = WifiCollectorResult.obtain();
                    wifiCollectorResult.setStartTime(wifiResultCollectorStartTime);
                    wifiCollectorResult.setEndTime(wifiresultCollectorEndTime);
                    wifiCollectorResult.setCollectorId(getTaskId());
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        wifiCollectorResult.setTimestamp(scanResult.timestamp);
                    } else {
                        wifiCollectorResult.setTimestamp(-1);
                    }
                    wifiCollectorResult.setCollectorRate(collectorConfig.wifiCollectorRate);
                    wifiCollectorResult.setSSID(scanResult.SSID);
                    wifiCollectorResult.setBSSID(scanResult.BSSID);
                    wifiCollectorResult.setCapatbilities(scanResult.capabilities);
                    wifiCollectorResult.setLevel(scanResult.level);
                    wifiCollectorResult.setFrequency(scanResult.frequency);
                    wifiCollectorResults.add(wifiCollectorResult);
                    //                    wifiCollectorResult.recycle();
                }

                handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_HANDLER_SCANRESULT);

                try {
                    Thread.sleep(collectorConfig.wifiCollectorRate);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (handler != null) {
                    handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_SCAN_SUCCESS);
                }
                return;
            } else {
                if (handler != null) {
                    try {
                        Thread.sleep(collectorConfig.wifiCollectorRate);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(HANDLER_MESSAGE_WIFI_SCANRESULT_NULL);
                }
                return;
            }
        }
    }

    private class WifiCollectorTaskHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case HANDLER_MESSAGE_WIFIMANAGER_NULL:
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGE_COLLECTOR_UNAVAILABLE);
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_STATE_DISABLED:
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGG_COLLECTOR_STATE_UNAVAILABLE);
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_STATE_ENABLING:
                    //正在打开，延时之后重试
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onFailed(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_FAILED_TYPE_COLLECTOR_STATE_OPENNING, NexdCollector.COLLECTOR_TASK_FAILED_MESSAGG_COLLECTOR_STATE_OPENNING);
                    }
                    if (!collectorTaskStoped) {
                        wifiResultCollectorStartTime = System.currentTimeMillis();
                        //                        TaskExecutor.startDelayedTask(getCollectorTask(), collectorConfig.wifiCollectorRate / 2, !collectorTaskStoped, TimeUnit.MILLISECONDS);
                        //                        getCollectorTask().executeAllowingLoss();
                        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(getCollectorTask());
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_STATE_UNKNOWN:
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGG_COLLECTOR_STATE_UNAVAILABLE);
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_SCANRESULT_NULL:
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onFailed(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_FAILED_TYPE_RESULT_NULL, NexdCollector.COLLECTOR_TASK_FAILED_MESSAGE_RESULT_NULL);
                    }
                    if (!collectorTaskStoped) {
                        wifiResultCollectorStartTime = System.currentTimeMillis();
                        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(getCollectorTask());
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_SCAN_SUCCESS:
                    if (!collectorTaskStoped) {
                        wifiResultCollectorStartTime = System.currentTimeMillis();
                        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(getCollectorTask());
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_HANDLER_SCANRESULT:
                    if (wifiCollectorListener != null && wifiCollectorResults != null) {
                        List<WifiCollectorResult> wifiCollectorResultList = new ArrayList<WifiCollectorResult>();
                        wifiCollectorResultList.addAll(wifiCollectorResults);
                        wifiCollectorListener.onSuccess(getTaskId(), wifiResultCollectorTime, wifiCollectorResultList);
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_WIFI_FUCK_360:
                    if (wifiCollectorListener != null) {
                        wifiCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_UNNATURE_ACCESS_DATA, NexdCollector.COLLECTOR_TASK_STOP_MESSAGE_UNNATURE_ACCESS_DATA);
                    }
                    Runtime.getRuntime().gc();
                    break;
            }
        }
    }
}
